#! /usr/bin/env python
# -*- coding: utf-8 -*-

# Copyright (c) JoinQuant Development Team
# Author: Huayong Kuang <kuanghuayong@joinquant.com>

#使用共享数组代替管道，将一个由浮点数组成的Python列表发送给另外一个进程
import multiprocessing

class FloatChannel(object):
    def __init__(self,maxsize):
        #在共享内存中创建一个试数组
        self.buffer=multiprocessing.RawArray('d',maxsize)
        #在共享内存中创建ctypes对象
        self.buffer_len=multiprocessing.Value('i')
        #定义一个信号量1代表：empty
        self.empty=multiprocessing.Semaphore(1)
        #定义一个信号量0代表：full
        self.full=multiprocessing.Semaphore(0)

    def send(self,values):
        #只在缓存为null时继续
        #acquire()会阻塞线程，直到release被调用
        self.empty.acquire()
        nitems=len(values)
        print("保存内容的长度",nitems)
        #设置缓冲区大小
        self.buffer_len.value=nitems
        #将值复制到缓冲区中
        self.buffer[:nitems]=values
        print(self.buffer[:nitems])
        #发信号通知缓冲区已满
        self.full.release()

    def recv(self):
        #只在缓冲区已满时继续
        self.full.acquire()
        #复制值
        values=self.buffer[:self.buffer_len.value]
        #发送信号，通知缓冲区为空
        self.empty.release()
        return values

#性能测试，接受多条消息
def consume_test(count,ch):
    #for i in range(count):
        values=ch.recv()
        print("接收到的值：",values)

#性能测试，发送多条消息
def produce_test(count,values,ch):
    #for i in range(count):
        print("发送：",values)
        ch.send(values)


if __name__=="__main__":
    ch=FloatChannel(10000)
    p=multiprocessing.Process(target=consume_test,args=(1000,ch))

    p.start()

    values=[float(x) for x in range(10)]

    produce_test(10,values,ch)

    print("done")

    p.join()
